<template>
  <view v-if="show" class="uni-noticebar" :style="{ backgroundColor: backgroundColor }" @click="onClick">
    <view v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon">
      <image :src="iconUrl"></image>
    </view>
    <view
      ref="textBox"
      class="uni-noticebar__content-wrapper"
      :class="{
        'uni-noticebar__content-wrapper--scrollable': scrollable,
        'uni-noticebar__content-wrapper--single': !scrollable && (single || moreText)
      }"
    >
      <view
        :id="elIdBox"
        class="uni-noticebar__content"
        :class="{
          'uni-noticebar__content--scrollable': scrollable,
          'uni-noticebar__content--single': !scrollable && (single || moreText)
        }"
      >
        <text
          :id="elId"
          ref="animationEle"
          class="uni-noticebar__content-text"
          :class="{
            'uni-noticebar__content-text--scrollable': scrollable,
            'uni-noticebar__content-text--single': !scrollable && (single || moreText)
          }"
          :style="{
            color: color,
            width: wrapWidth + 'px',
            animationDuration: animationDuration,
            '-webkit-animationDuration': animationDuration,
            animationPlayState: webviewHide ? 'paused' : animationPlayState,
            '-webkit-animationPlayState': webviewHide ? 'paused' : animationPlayState,
            animationDelay: animationDelay,
            '-webkit-animationDelay': animationDelay
          }"
          >{{ text }}</text
        >
      </view>
    </view>
    <view
      v-if="showGetMore === true || showGetMore === 'true'"
      class="uni-noticebar__more uni-cursor-point"
      @click="clickMore"
    >
      <text v-if="moreText" :style="{ color: moreColor }" class="uni-noticebar__more-text">{{ moreText }}</text>
    </view>
  </view>
</template>
<script>
// #ifdef APP-NVUE
const dom = weex.requireModule('dom');
const animation = weex.requireModule('animation');
// #endif

/**
 * NoticeBar 自定义导航栏
 * @description 通告栏组件
 * @property {Number} speed 文字滚动的速度，默认100px/秒
 * @property {String} text 显示文字
 * @property {String} backgroundColor 背景颜色
 * @property {String} color 文字颜色
 * @property {String} moreColor 查看更多文字的颜色
 * @property {String} moreText 设置“查看更多”的文本
 * @property {Boolean} single = [true|false] 是否单行
 * @property {Boolean} scrollable = [true|false] 是否滚动，为true时，NoticeBar为单行
 * @property {Boolean} showIcon = [true|false] 是否显示左侧喇叭图标
 * @property {Boolean} showClose = [true|false] 是否显示左侧关闭按钮
 * @property {Boolean} showGetMore = [true|false] 是否显示右侧查看更多图标，为true时，NoticeBar为单行
 * @event {Function} click 点击 NoticeBar 触发事件
 * @event {Function} close 关闭 NoticeBar 触发事件
 * @event {Function} getmore 点击”查看更多“时触发事件
 */

export default {
  name: 'UniNoticeBar',
  props: {
    text: {
      type: String,
      default: ''
    },
    moreText: {
      type: String,
      default: ''
    },
    backgroundColor: {
      type: String,
      default: '#fffbe8'
    },
    speed: {
      // 默认1s滚动100px
      type: Number,
      default: 100
    },
    color: {
      type: String,
      default: '#de8c17'
    },
    moreColor: {
      type: String,
      default: '#999999'
    },
    single: {
      // 是否单行
      type: [Boolean, String],
      default: false
    },
    scrollable: {
      // 是否滚动，添加后控制单行效果取消
      type: [Boolean, String],
      default: false
    },
    showIcon: {
      // 是否显示左侧icon
      type: [Boolean, String],
      default: false
    },
    iconUrl: {
      type: String,
      default: ''
    },
    showGetMore: {
      // 是否显示右侧查看更多
      type: [Boolean, String],
      default: false
    },
    showClose: {
      // 是否显示左侧关闭按钮
      type: [Boolean, String],
      default: false
    }
  },
  data() {
    const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`;
    const elIdBox = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`;
    return {
      textWidth: 0,
      boxWidth: 0,
      wrapWidth: '',
      webviewHide: false,
      // #ifdef APP-NVUE
      stopAnimation: false,
      // #endif
      elId: elId,
      elIdBox: elIdBox,
      show: true,
      animationDuration: 'none',
      animationPlayState: 'paused',
      animationDelay: '0s'
    };
  },
  mounted() {
    // #ifdef APP-PLUS
    var pages = getCurrentPages();
    var page = pages[pages.length - 1];
    var currentWebview = page.$getAppWebview();
    currentWebview.addEventListener('hide', () => {
      this.webviewHide = true;
    });
    currentWebview.addEventListener('show', () => {
      this.webviewHide = false;
    });
    // #endif
    this.$nextTick(() => {
      this.initSize(this.scrollable);
    });
  },

  /**
   * 数据监听
   * @type {Object}
   */
  watch: {
    speed() {
      this.$nextTick(() => {
        this.initSize(this.text.length > 15 ? true : false);
      });
    },
    text(newValue) {
      this.$nextTick(() => {
        this.initSize(newValue.length > 15 ? true : false);
      });
    }
  },
  // #ifdef APP-NVUE
  beforeDestroy() {
    this.stopAnimation = true;
  },
  // #endif
  methods: {
    initSize(scrollable = false) {
      if (scrollable) {
        // #ifndef APP-NVUE
        let query = [],
          boxWidth = 0,
          textWidth = 0;
        let textQuery = new Promise((resolve, reject) => {
          uni
            .createSelectorQuery()
            // #ifndef MP-ALIPAY
            .in(this)
            // #endif
            .select(`#${this.elId}`)
            .boundingClientRect()
            .exec(ret => {
              this.textWidth = ret[0].width;
              resolve();
            });
        });
        let boxQuery = new Promise((resolve, reject) => {
          uni
            .createSelectorQuery()
            // #ifndef MP-ALIPAY
            .in(this)
            // #endif
            .select(`#${this.elIdBox}`)
            .boundingClientRect()
            .exec(ret => {
              this.boxWidth = ret[0].width;
              resolve();
            });
        });
        query.push(textQuery);
        query.push(boxQuery);
        Promise.all(query).then(() => {
          this.animationDuration = `${this.textWidth / this.speed}s`;
          this.animationDelay = `-${this.boxWidth / this.speed}s`;
          setTimeout(() => {
            this.animationPlayState = 'running';
          }, 1000);
        });
        // #endif
        // #ifdef APP-NVUE
        dom.getComponentRect(this.$refs['animationEle'], res => {
          let winWidth = uni.getSystemInfoSync().windowWidth;
          this.textWidth = res.size.width;
          animation.transition(
            this.$refs['animationEle'],
            {
              styles: {
                transform: `translateX(-${winWidth}px)`
              },
              duration: 0,
              timingFunction: 'linear',
              delay: 0
            },
            () => {
              if (!this.stopAnimation) {
                animation.transition(
                  this.$refs['animationEle'],
                  {
                    styles: {
                      transform: `translateX(-${this.textWidth}px)`
                    },
                    timingFunction: 'linear',
                    duration: ((this.textWidth - winWidth) / this.speed) * 1000,
                    delay: 1000
                  },
                  () => {
                    if (!this.stopAnimation) {
                      this.loopAnimation();
                    }
                  }
                );
              }
            }
          );
        });
        // #endif
      }
      // #ifdef APP-NVUE
      if (!scrollable && (this.single || this.moreText)) {
        dom.getComponentRect(this.$refs['textBox'], res => {
          this.wrapWidth = res.size.width;
        });
      }
      // #endif
    },
    loopAnimation() {
      // #ifdef APP-NVUE
      animation.transition(
        this.$refs['animationEle'],
        {
          styles: {
            transform: `translateX(0px)`
          },
          duration: 0
        },
        () => {
          if (!this.stopAnimation) {
            animation.transition(
              this.$refs['animationEle'],
              {
                styles: {
                  transform: `translateX(-${this.textWidth}px)`
                },
                duration: (this.textWidth / this.speed) * 1000,
                timingFunction: 'linear',
                delay: 0
              },
              () => {
                if (!this.stopAnimation) {
                  this.loopAnimation();
                }
              }
            );
          }
        }
      );
      // #endif
    },
    clickMore() {
      this.$emit('getmore');
    },
    close() {
      this.show = false;
      this.$emit('close');
    },
    onClick() {
      this.$emit('click');
    }
  }
};
</script>
<style lang="scss" scoped>
.uni-noticebar {
  /* #ifndef APP-NVUE */
  display: flex;
  width: 100%;
  box-sizing: border-box;
  /* #endif */
  flex-direction: row;
  align-items: center;
  padding: 12px 24px;
}

.uni-cursor-point {
  /* #ifdef H5 */
  cursor: pointer;
  /* #endif */
}

.uni-noticebar-close {
  margin-right: 10px;
}

.uni-noticebar-icon {
  margin-right: 10px;

  image {
    margin-top: 5px;
    width: 40px;
    height: 40px;
  }
}

.uni-noticebar__content-wrapper {
  flex: 1;
  flex-direction: column;
  overflow: hidden;
}

.uni-noticebar__content-wrapper--single {
  /* #ifndef APP-NVUE */
  line-height: 40px;
  /* #endif */
}

.uni-noticebar__content-wrapper--single,
.uni-noticebar__content-wrapper--scrollable {
  flex-direction: row;
}

/* #ifndef APP-NVUE */
.uni-noticebar__content-wrapper--scrollable {
  position: relative;
  height: 40px;
}

/* #endif */

.uni-noticebar__content--scrollable {
  /* #ifdef APP-NVUE */
  flex: 0;
  /* #endif */
  /* #ifndef APP-NVUE */
  flex: 1;
  display: block;
  overflow: hidden;
  /* #endif */
}

.uni-noticebar__content--single {
  /* #ifndef APP-NVUE */
  display: flex;
  flex: none;
  width: 100%;
  justify-content: center;
  /* #endif */
}

.uni-noticebar__content-text {
  font-size: 24px;
  line-height: 40px;
  /* #ifndef APP-NVUE */
  word-break: break-all;
  /* #endif */
}

.uni-noticebar__content-text--single {
  /* #ifdef APP-NVUE */
  lines: 1;
  /* #endif */
  /* #ifndef APP-NVUE */
  display: block;
  width: 100%;
  white-space: nowrap;
  /* #endif */
  overflow: hidden;
  text-overflow: ellipsis;
}

.uni-noticebar__content-text--scrollable {
  /* #ifdef APP-NVUE */
  lines: 1;
  padding-left: 750px;
  /* #endif */
  /* #ifndef APP-NVUE */
  position: absolute;
  display: block;
  height: 40px;
  line-height: 40px;
  white-space: nowrap;
  padding-left: 100%;
  animation: notice 10s 0s linear infinite both;
  animation-play-state: paused;
  /* #endif */
}

.uni-noticebar__more {
  /* #ifndef APP-NVUE */
  display: inline-flex;
  /* #endif */
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  padding-left: 10px;
}

.uni-noticebar__more-text {
  font-size: 24px;
}

@keyframes notice {
  100% {
    transform: translate3d(-100%, 0, 0);
  }
}
</style>
